package com.mammoth.Bodybuilding.service.Impl;

import java.util.Date;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import javax.servlet.http.HttpServletRequest;
import javax.transaction.Transactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.querydsl.QPageRequest;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.validation.BindingResult;

import com.mammoth.Bodybuilding.entity.ResultObj;
import com.mammoth.Bodybuilding.entity.SysRole;
import com.mammoth.Bodybuilding.entity.SysUserObj;
import com.mammoth.Bodybuilding.respository.IRoleRepository;
import com.mammoth.Bodybuilding.respository.IUserRepository;
import com.mammoth.Bodybuilding.service.IUserService;
import com.mammoth.Bodybuilding.util.ClientType;
import com.mammoth.Bodybuilding.util.CurrencySaas;
import com.mammoth.Bodybuilding.util.EmailUtil;
import com.mammoth.Bodybuilding.util.MD5Util;
import com.mammoth.Bodybuilding.util.RoleType;

/**
 * 
 * @title : UserServiceImpl
 * @description : 用户 服务层实现
 * @company : com.mammoth.Bodybuilding.service.Impl
 * @project Mammoth
 * @author xingzhaojun
 * @date 2018年4月16日 下午4:54:54
 */
@Service
@Transactional
public class UserServiceImpl implements IUserService, UserDetailsService {

	/** 定义一个全局的记录器，通过LoggerFactory获取 **/
	private final static Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);

	/** 注入用户数据仓库 **/
	@Autowired
	private IUserRepository userRespository;

	/** 注入角色数据仓库 **/
	@Autowired
	private IRoleRepository roleRespository;

	/** redis注入 **/
	@Autowired
	private StringRedisTemplate stringRedisTemplate;

	/** 注入邮件工具 **/
	@Autowired
	private EmailUtil emailUtil;

	/**
	 * 注册用户接口
	 * 
	 * @param user
	 *            用户信息
	 * @param objects
	 *            [确认密码，终端类型，验证信息]
	 * @return
	 */
	@Override
	public ResultObj registUser(SysUserObj user, Object... objects) {
		/** 初始化临时变量 **/
		ResultObj resultObj = new ResultObj();
		String clientType = new String();
		String checkPass = new String();
		/** 获取数据并校验 **/
		if (objects != null) {
			for (Object object : objects) {
				/** 判断是否是终端类型 **/
				if (object.getClass().equals(ClientType.class)) {
					/** 获取终端类型 **/
					ClientType value = ClientType.valueOf(object.toString());
					clientType = value.name();
				}
				/** 判断是否是字符串类型 **/
				if (object.getClass().equals(String.class)) {
					checkPass = object.toString();
				}
				/** 判断是否是校验对象 **/
				if (object.getClass().equals(BindingResult.class)) {
					/** 校验用户 **/
					resultObj = CurrencySaas.checkFieldError((BindingResult) object);
					/** 判断是否通过校验 **/
					if (!resultObj.isFlag()) {
						resultObj.setMessage(resultObj.getMessage() + ",请稍后重新注册!");
						/** 记录错误日志 **/
						logger.error(resultObj.getMessage());
						return resultObj;
					}
				}
			}
			/** 判读密码与确认密码是否一致 **/
			if (!user.getPassword().equals(checkPass)) {
				resultObj.setCode(-1);
				resultObj.setFlag(false);
				resultObj.setMessage("警告!密码与确认密码不一致，请稍后重新注册!");
				/** 记录错误日志 **/
				logger.error(resultObj.getMessage());
				return resultObj;
			}
			/** 判断用户名是否重复 **/
			Optional<SysUserObj> temp = userRespository.findByUsername(user.getLoginName());
			if (temp.isPresent()) {
				resultObj.setCode(-1);
				resultObj.setFlag(false);
				resultObj.setMessage("警告!用户名已存在，请稍后重新注册!");
				/** 记录错误日志 **/
				logger.error(resultObj.getMessage());
				return resultObj;
			}
			/** 判断手机号是否已经被注册 **/
			Optional<SysUserObj> temp1 = userRespository.findByPhoneNum(user.getPhoneNum());
			if (temp1.isPresent()) {
				resultObj.setCode(-1);
				resultObj.setFlag(false);
				resultObj.setMessage("警告!用户手机号码已经注册!");
				/** 记录错误日志 **/
				logger.error(resultObj.getMessage());
				return resultObj;
			}
			/** 验证结束 **/
			/** 密码加密 **/
			user.setPassword(MD5Util.encode(user.getPassword()));
			/** 保存用户 **/
			try {
				/** 设置当前用户终端 **/
				user.setClientType(clientType);
				/** 设置创建时间 **/
				user.setCreateTime(new Date());
				/** 设置默认头像 **/
				user.setHeadIMG("/global/assets/img/ui-sam.jpg");
				/** 查找权限 **/
				SysRole rolses = roleRespository.findByRoleName("ROLE_USER");
				/** 设置权限 **/
				user.setSysRoles(rolses);
				/** 判断是否是移动端用户注册 **/
				if (!user.getClientType().equals(ClientType.PCMANAGETYPE.toString())) {
					user.setInvitationCode(user.getPhoneNum());
				}
				user.setInvitationCode(user.getPhoneNum());
				user.setIntegral((long) 0);
				user.setExperience((long) 0);
				SysUserObj save = userRespository.save(user);
				resultObj.setCode(1);
				resultObj.setFlag(true);
				resultObj.setMessage("恭喜!用户注册成功,请登录");
				resultObj.setResult(save);
				/** 记录错误日志 **/
				logger.info(resultObj.getMessage());
			} catch (Exception e) {
				resultObj.setCode(-1);
				resultObj.setFlag(false);
				resultObj.setMessage("警告!用户数据保存异常，请稍后重新注册!");
				/** 记录错误日志 **/
				logger.error(resultObj.getMessage());
				// e.printStackTrace();
			}
		}
		return resultObj;
	}

	/***
	 * 加载用户信息方法
	 */
	@Override
	public UserDetails loadUserByUsername(String loginName) throws UsernameNotFoundException {
		Optional<SysUserObj> sysUser = userRespository.findByUsername(loginName);
		if (!sysUser.isPresent()) {
			throw new UsernameNotFoundException("用户名不存在");
		}
		return sysUser.get();
	}

	/**
	 * 忘记密码
	 * 
	 * @param loginName
	 *            登录名
	 * @param request
	 *            request 对象
	 * @return
	 */
	@Override
	public ResultObj forgetPassword(String loginName, HttpServletRequest request) {
		ResultObj result = new ResultObj();
		Optional<SysUserObj> tempUser = userRespository.findByUsername(loginName);
		if (tempUser.isPresent()) {
			String email = tempUser.get().getEmail();
			String uuid = UUID.randomUUID().toString().replaceAll("-", "");
			/** 向redis中添加用户id **/
			stringRedisTemplate.opsForValue().set(uuid, tempUser.get().getId().toString(), 60 * 30, TimeUnit.SECONDS);
			StringBuffer html = new StringBuffer();
			html.append("<h1>猛犸健身-找回密码</h1>");
			html.append("<p>请访问<a href=" + request.getRequestURL() + "/" + uuid + ">" + request.getRequestURL() + "/"
					+ uuid + "</a>修改密码!<p>");
			emailUtil.sendHtmlMail(email, "猛犸健身-找回密码", html.toString());
			result.setCode(1);
			result.setFlag(true);
			result.setMessage("电子邮件发送成功,请前去登录电子邮件以重置密码!");
		} else {
			result.setCode(-1);
			result.setFlag(false);
			result.setMessage("用户不存在,请检查后重试");
		}
		return result;
	}

	/**
	 * 重置密码
	 * 
	 * @param uuid
	 *            标识id
	 * @param password
	 *            新密码
	 * @param checkpassword
	 *            确认密码
	 * @return
	 */
	@Override
	public ResultObj resetPassword(String uuid, String password, String checkpassword) {
		ResultObj resultObj = new ResultObj();
		/** 验证密码与确认密码 **/
		if (!password.equals(checkpassword)) {
			resultObj.setCode(-2);
			resultObj.setFlag(false);
			resultObj.setMessage("密码与确认密码不一致");
			return resultObj;
		}
		String userId = stringRedisTemplate.opsForValue().get(uuid);
		if (userId == null) {
			resultObj.setCode(-3);
			resultObj.setFlag(false);
			resultObj.setMessage("忘记密码请求时间过长，请至忘记密码重试！");
			return resultObj;
		}
		/** 根据id获取用户对象 **/
		Optional<SysUserObj> findById = userRespository.findById(Long.parseLong(userId));
		if (findById.isPresent()) {
			/** 修改密码 **/
			SysUserObj sysUserObj = findById.get();
			sysUserObj.setPassword(MD5Util.encode(password));
			/** 重新保存用户 **/
			userRespository.save(sysUserObj);
			resultObj.setCode(1);
			resultObj.setFlag(true);
			resultObj.setMessage("密码修改成功,请登录!");
		} else {
			resultObj.setCode(-3);
			resultObj.setFlag(false);
			resultObj.setMessage("修改密码失败,用户不存在");
		}
		return resultObj;
	}

	/***
	 * 根据条件查询用户
	 */
	@Override
	public ResultObj getAllUser(int pageSize, int pageIndex, String name, String tel) {
		ResultObj resultObj = new ResultObj();
		Pageable pageable = new QPageRequest(pageIndex - 1, pageSize);
		Page<SysUserObj> page = userRespository.getAllUserNotHasprogram(pageable, RoleType.ROLE_PROGRAM.toString(),
				name, tel);
		resultObj.setCode(1);
		resultObj.setFlag(true);
		resultObj.setTotal(page.getTotalElements());
		resultObj.setResult(page.getContent());
		resultObj.setMessage("查询成功");
		return resultObj;
	}

	/**
	 * 根据用户id删除用户
	 */
	@Override
	public ResultObj deleteUsers(Long[] id) {
		ResultObj resultObj = new ResultObj();
		try {
			for (Long idNum : id) {
				userRespository.deleteById(idNum);
			}
			resultObj.setCode(1);
			resultObj.setFlag(true);
			resultObj.setMessage("用户删除完成");
			/** 记录日志 **/
			logger.info(resultObj.getMessage());
		} catch (Exception e) {
			resultObj.setFlag(false);
			resultObj.setCode(-1);
			resultObj.setMessage("删除用户发生错误");
		}
		return resultObj;
	}

	/**
	 * 高管修改用户信息
	 */
	@Override
	public ResultObj updateUser(String loginName, String nickName, String phoneNum, String email, String role) {
		ResultObj resultObj = new ResultObj();
		Optional<SysUserObj> users = userRespository.findByUsername(loginName);
		if (users.isPresent()) {
			SysUserObj user = users.get();
			user.setNickName(nickName);
			user.setPhoneNum(phoneNum);
			user.setEmail(email);
			Optional<SysRole> roles = roleRespository.findById(Long.parseLong(role));
			if (roles.isPresent()) {
				user.setSysRoles(roles.get());
			}
			/**重新保存用户**/
			userRespository.save(user);
			resultObj.setCode(1);
			resultObj.setFlag(true);
			resultObj.setMessage("修改用户信息成功");
		} else {
			resultObj.setCode(-1);
			resultObj.setFlag(false);
			resultObj.setMessage("需要修改的用户不存在");
		}
		return resultObj;
	}

}
